home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir42
/
c7105.zip
/
RELATION.TPX
< prev
next >
Wrap
Text File
|
1994-03-02
|
61KB
|
876 lines
#!┌───────────────────────────┤Template Segment├───────────┬─────────────────┐
#!│ Relation.TPX │Version: 3007.105│
#!├───────────────────────────────┤Contents├───────────────┴─────────────────┤
#!│Structure Type Description │
#!│──────────────────── ───────── ─────────────────────────────────────────│
#!│RIUpdates GROUP │
#!│WriteUpdates GROUP │
#!│RIDeletes GROUP │
#!│WriteDeletes GROUP │
#!│InitLogout GROUP │
#!│BtrieveTrxFraming GROUP │
#!│SavePrimaryLinks GROUP │
#!│ConcurrentWrite GROUP │
#!│ConcurrentDelete GROUP │
#!│DriverCheck GROUP │
#!│PrimaryDriverCheck GROUP │
#!├───────────────────────────────┤Comments├─────────────────────────────────┤
#!│Version Comments │
#!│──────── ────────────────────────────────────────────────────────────────│
#!│3007.000 Release of CDD3 version 3007 templates │
#!│3007.101 Repaired RIUpdates GROUP │
#!│ Repaired RIDeletes GROUP │
#!│ Modified PrimaryDriverCheck GROUP │
#!│ Modified DriverCheck GROUP │
#!│3007.103 Repaired RIUpdates GROUP │
#!│ Repaired RIDeletes GROUP │
#!│3007.105 Repaired InitLogout GROUP │
#!│ Repaired BtrieveTrxFraming GROUP │
#!└──────────────────────────────────────────────────────────────────────────┘
#!
#!***************************************************************************
#GROUP(%RIUpdates) #!Perform Referential Updates
#!
#!┌────────────────────────────┤Template Group├────────────┬─────────────────┐
#!│ RIUpdates │Version: 3007.103│
#!├──────────────────────────────┤Description├─────────────┴─────────────────┤
#!│Purpose: Constructs RI Update code │
#!│Called From: FORM.TPX and MULTIPG.TPX (Near the end) │
#!│Assumptions: None │
#!│Inserts: WriteUpdates (perform RI updates) │
#!│ InitLogout (performs transaction logging) │
#!│ RIRestrictMsg (warns user if constrained as restricted) │
#!│ AbortTransactionMsg (warns user if transaction aborted) │
#!│ RIUpdateError (warns user on RI update error) │
#!│Symbols Set: None │
#!│Notes: None │
#!├───────────────────────────────┤Comments├─────────────────────────────────┤
#!│Version Comments │
#!│──────── ────────────────────────────────────────────────────────────────│
#!│3007.000 Release of CDD3 version 3007 templates │
#!│3007.101 Repaired code generating the %LogoutList symbol. Primary needed│
#!│ to be added to the list. │
#!│3007.103 Moved AbortTransactionMsg #INSERT to build and display the │
#!│ message before the ROLLBACK occurs. This was done because │
#!│ the error is reset after ROLLBACK. In addition, the ShowWarning│
#!│ was removed from the AbortTransactionMsg #GROUP and placed after│
#!│ the ROLLBACK. │
#!└──────────────────────────────────────────────────────────────────────────┘
#!
#FOR(%File) #! Cycle through each file
#SET(%FileIsParent,%Null) #! Is the file a parent?
#SET(%FileIsChild,%Null) #! Is the file a child?
#SET(%RIUpdateNeeded,%Null) #! Is an RI Update necessary?
#SET(%CheckPre,('['&%FilePre&']')) #! Setup to find %File Prefix
#IF((INSTRING(%CheckPre,%UpdateParentList,1,1)))#!Search for file as parent
#SET(%FileIsParent,'TRUE') #! If it is, set that flag
#SET(%RIUpdateNeeded,'TRUE') #! And RI Routine is needed
#ENDIF #! END (IF a Parent)
#IF((INSTRING(%CheckPre,%UpdateChildList,1,1)))#! Search for file as child
#SET(%FileIsChild,'TRUE') #! If it is, set that flag
#SET(%RIUpdateNeeded,'TRUE') #! And RI Routine is needed
#ENDIF #! END (IF a Child)
#IF(%RIUpdateNeeded) #! If either parent or child
#IF(%FIleIsChild) #! If a child relation in proc
#FOR(%Relation) #! For every relation
#SET(%RelationString,('['&%RelationPre&'∙'&%FilePre&']'))
#! Setup to find relationship
#! between file and parents
#IF((INSTRING(%RelationString,%UpdateRelations,1,1)))
#! If the relation was
#! flagged for RI Code Generation
#INSERT(%WriteUpdates) #! Write the update code
#ENDIF #! END (IF the relation...)
#ENDFOR #! END (FOR every relation...)
#ELSE #! ELSE (If not child)
#! (Should only apply to
#! %Primary)
#INSERT(%WriteUpdates) #! Write the update code
#ENDIF #! END (IF a Child)
#ENDIF #! END (IF RI Update needed)
#ENDFOR #! END (FOR File)
#IF(%UpdateChildList) #!IF RI Update Children
!─────────────────────────────────────────────────────────────────────────────
ConstrainedUpdate ROUTINE #<!Perform RI Updates
CLEAR(RI:RestrictUpdate,0) #<! Clear Restrict Flag
CLEAR(AbortTransaction,0) #<! Clear ABORT flag
DO OpenRIUpdateFiles #<! Open files used
#SET(%LogoutFrom,'Update')
#INSERT(%InitLogout) #!Insert Logout Code
DO Update:%Primary #<! Perform the Updates
IF RI:RestrictUpdate #<! If update was restricted
#INSERT(%RIRestrictMsg) #! Alert the User
#IF(%NoLogoutSupport=%Null) #!If supporting logout
ROLLBACK #<! Rollback transaction
#ENDIF #!END (If supporting logout)
AbortTransaction = True #<! Set the ABORT flag
#IF(%CloseFiles)
DO CloseRIUpdateFiles
#ENDIF
EXIT #<! and exit the routine
END #<! END (If restricted update)
PUT(%Primary) #<! Put %Primary
#IF(%NoLogoutSupport=%Null) #!If supporting logout
IF ~ERRORCODE() #<! If the Parent update Ok
COMMIT #<! Commit the transaction
ELSE #<! else on any error
AbortTransaction = True #<! Set the ABORT flag
#INSERT(%AbortTransactionMsg) #! Alert the user
ROLLBACK #<! Rollback the transaction
ShowWarning ! Show warning
END #<! End If ErrorCode()
#ELSE #!NoLogoutSupport
IF ERRORCODE() #<! Was the update ok?
AbortTransaction = True #<! Set the ABORT flag
#INSERT(%RIUpdateError) #! Alert the User
END ! END (If ErrorCode)
#ENDIF #!END (If supporting logout)
#IF(%CloseFiles)
DO CloseRIUpdateFiles
#ENDIF
EXIT #<! Exit the ROUTINE
!─────────────────────────────────────────────────────────────────────────────
OpenRIUpdateFiles ROUTINE #<!Open files used in update
#FOR(%File) #!For Each File
#SET(%ChildString,('['&%FilePre&']')) #!Setup to find as child
#IF((INSTRING(%ChildString,%UpdateChildList,1,1)))#!If %File is Child
#IF(%CloseFiles) #!If Closing opened files
%FilePre::Opened = CheckOpen(%File) #<! Open %FIle (If Necessary)
#ELSE #!ELSE (If not closing files)
CheckOpen(%File) #<! Open %FIle (If Necessary)
#ENDIF #!END (If Closing open files)
#ENDIF #!END (If file is child)
#ENDFOR #!END (For Each File)
#IF(%CloseFiles)
!─────────────────────────────────────────────────────────────────────────────
CloseRIUpdateFiles ROUTINE
#FOR(%File) #!For Each File
#SET(%ChildString,('['&%FilePre&']')) #!Setup to find as child
#IF((INSTRING(%ChildString,%UpdateChildList,1,1)))#!If %File is Child
IF %FilePre::Opened THEN CLOSE(%File). #<! IF Opened here, close here
#ENDIF #!END (If file is child)
#ENDFOR #!END (For Each File)
#ENDIF
#ENDIF #!END (If update Child)
#!***************************************************************************
#GROUP(%WriteUpdates) #!Perform Referential Updates
#IF(%FileIsChild) #!If part of child relationship
!─────────────────────────────────────────────────────────────────────────────
Update:%RelationPre::%FilePre ROUTINE #<!%Relation - %File
! Constraint: %RelationConstraintUpdate
#ELSE #!Otherwise (Parent Only)
!─────────────────────────────────────────────────────────────────────────────
Update:%File ROUTINE #<!RI Update of %File
#ENDIF #!END (If Child)
#SET(%SaveFile,%File) #!Save the value of %File
#SET(%SaveRelation,%Relation) #!And the value of %Relation
#IF(%FileIsChild) #!Is the file a child
#!(This code applies to all
#! files but %Primary)
#FIX(%File,%SaveRelation) #!And swap the relationship
#FIX(%Relation,%SaveFile) #!for correct symbol access
#SET(%KeyFieldCounter,'0') #!Clear Field Counter
#FOR(%RelationKeyField) #!For each field in key
#IF(%RelationKeyFieldLink) #!If the field is linked
#SET(%KeyFieldCounter,(%KeyFieldCounter+1))#!Increment Field Counter
#ENDIF #!END (If field is linked)
#ENDFOR #!END (For relation field)
#SET(%IfWritten,%Null) #!Prepare For If Structure
#FOR(%RelationKeyField) #!For each field in key
#IF(%KeyFieldCounter='1') #!If this is last link field
#IF(%IfWritten) #!If the IF statement written
AND %RelationKeyFieldLink = %RelationPre::%RelationKeyFieldLink #<! Check against save value
#ELSE #!If IF not written yet
IF %RelationKeyFieldLink = %RelationPre::%RelationKeyFieldLink #<! Check against save value
#ENDIF #!END (If IF Written)
#BREAK #!Break out of loop
#ELSE #!otherwise (Counter > 1)
#IF(%IfWritten) #!If the IF statement written
AND %RelationKeyFieldLink = %RelationPre::%RelationKeyFieldLink|#<! Check against save value
#ELSE #!If IF not written yet
IF %RelationKeyFieldLink = %RelationPre::%RelationKeyFieldLink|#<! Check against save value
#ENDIF #!END (If IF Written)
#ENDIF #!END (If Field Counter = 1)
#SET(%KeyFieldCounter,(%KeyFieldCounter-1)) #!Decrement Counter
#SET(%IfWritten,'TRUE') #!The IF statement written
#ENDFOR #!END (For Relation Field)
EXIT #<! If Save Value Match, Exit
END #<! END (If Save Values Match)
#FIX(%File,%SaveRelation) #!And swap the relationship
#FIX(%Relation,%SaveFile) #!for correct symbol access
GET(%Relation,0) #<! Disconnect record buffer
CLEAR(%RelationPre:Record,-1) #<! Clear record
#SET(%KeyFieldCounter,'0') #!Clear Field Counter
#!Field Counter is used to
#!construct a readable IF
#!structure inside loop.
#!Inside the loop, we search
#!each field of key, but use
#!Field Counter instead of
#!%RelationalKeyFieldLink
#FOR(%RelationKeyField) #!For each field in key
#IF(%RelationKeyFieldLink) #!If the field is linked
#SET(%KeyFieldCounter,(%KeyFieldCounter+1))#!Increment Field Counter
%RelationKeyField = %RelationPre::%RelationKeyFieldLink #<! Set to original value
#ENDIF #!END (If field is linked)
#ENDFOR #!END (For relation field)
SET(%RelationKey,%RelationKey) #<! Set for sequential access
LOOP ! Search through records
NEXT(%Relation) #<! Get the next record
IF ERRORCODE() THEN BREAK. ! If out of records, break.
#SET(%IfWritten,%Null) #!Prepare For If Structure
#FOR(%RelationKeyField) #!For each field in key
#IF(%KeyFieldCounter='1') #!If this is last link field
#IF(%IfWritten) #!If the IF statement written
OR %RelationKeyField <> %RelationPre::%RelationKeyFieldLink #<! Check against save value
#ELSE #!If IF not written yet
IF %RelationKeyField <> %RelationPre::%RelationKeyFieldLink #<! Check against save value
#ENDIF #!END (If IF Written)
#BREAK #!Break out of loop
#ELSE #!otherwise (Counter > 1)
#IF(%IfWritten) #!If the IF statement written
OR %RelationKeyField <> %RelationPre::%RelationKeyFieldLink|#<! Check against save value
#ELSE #!If IF not written yet
IF %RelationKeyField <> %RelationPre::%RelationKeyFieldLink|#<! Check against save value
#ENDIF #!END (If IF Written)
#ENDIF #!END (If Field Counter = 1)
#SET(%KeyFieldCounter,(%KeyFieldCounter-1)) #!Decrement Counter
#SET(%IfWritten,'TRUE') #!The IF statement written
#ENDFOR #!END (For Relation Field)
BREAK ! Break out of update loop
END ! END (If out of range)
#IF(%RelationConstraintUpdate = 'RESTRICT') #!If RESTRICTed update
ri:RestrictUpdate = True #<! Set Restricted Update flag
#FOR(%RelationKeyField) #!For each field in key
#IF(%RelationKeyFieldLink) #!If the field is linked
%RelationKeyFieldLink = %RelationPre::%RelationKeyFieldLink #<! Set to original condition
#ENDIF #!END (If field is linked)
#ENDFOR #!END (For relation field)
DISPLAY() ! Redisplay reset values
BREAK ! BREAK from processing loop
#ELSE #!ELSE (If not RESTRICT)
#IF(%FileIsParent) #!If the file is a parent
#FIX(%File,%SaveFile) #!Reset the file to original
#FOR(%Relation) #!For each relationship
#SET(%RelationString,('['&%FilePre&'∙'&%RelationPre&']'))
#!Setup to find relationship
#IF((INSTRING(%RelationString,%UpdateRelations,1,1)))
#!Search for Relationship
#!In Update Relation List
#FOR(%RelationKeyField) #!For Each Field of Key
#IF(%RelationKeyFieldLink) #!If the field is linked
%RelationPre::%RelationKeyFieldLink = %RelationKeyFieldLink #<! Save Link Field Value
#ENDIF #!END (IF Field is linked)
#ENDFOR #!END (FOR Each Key Field)
#ENDIF #!END (IF valid relation)
#ENDFOR #!END (FOR each relation)
#ENDIF #!END (IF the file is parent)
#FIX(%File,%SaveRelation) #!FIX to process REL as FILE
#FIX(%Relation,%SaveFile) #!FIX to process FILE as REL
#IF(%RelationConstraintUpdate = 'CASCADE') #!IF CASCADE constraint
#FOR(%RelationKeyField) #!For each field in key
#IF(%RelationKeyFieldLink) #!If the field is linked
%RelationKeyField = %RelationKeyFieldLink #<! Set to new value
#ENDIF #!END (If field is linked)
#ENDFOR #!END (For relation field)
#ELSE #!ELSE (IF not CASCADE)
#FOR(%RelationKeyField) #!For each field in key
#IF(%RelationKeyFieldLink) #!If the field is linked
CLEAR(%RelationKeyField,0) #<! Clear link field value
#ENDIF #!END (If field is linked)
#ENDFOR #!END (For relation field)
#ENDIF #!ELSE (IF not CASCADE)
#FIX(%File,%SaveFile) #!Reset the file to original
#IF(%FileIsParent) #!If the file is a parent
#FOR(%Relation) #!For each relationship
#SET(%RelationString,('['&%FilePre&'∙'&%RelationPre&']'))
#!Setup to find relationship
#IF((INSTRING(%RelationString,%UpdateRelations,1,1)))
#!Search for Relationship
#!In Update Relation List
DO Update:%FilePre::%RelationPre #<! Call Update Routine
IF ri:RestrictUpdate THEN EXIT. ! If Restrict then exit
#ENDIF #!END (IF valid relation)
#ENDFOR #!END (FOR each relation)
#ENDIF #!END (IF File is Parent)
PUT(%File) #<! PUT updated record
#ENDIF #!END (If RESTRICT Constraint)
END ! END loop
EXIT ! Exit to calling routine
#ELSE #!ELSE (If NOT a child)
#!This applies only to
#!%Primary
#FOR(%Relation) #!For each Relation
#SET(%RelationString,('['&%FilePre&'∙'&%RelationPre&']'))
#!Setup to find relationship
#IF((INSTRING(%RelationString,%UpdateRelations,1,1)))
#!Search for Relationship
#!In Update Relation List
DO Update:%FilePre::%RelationPre #<! Call Update Routine
IF ri:RestrictUpdate THEN EXIT. ! If Restrict then exit
#ENDIF #!END (IF valid relation)
#ENDFOR #!END (FOR each relation)
EXIT #<! Exit to calling routine
#ENDIF #!ELSE (File is child)
#!***************************************************************************
#!
#!┌────────────────────────────┤Template Group├────────────┬─────────────────┐
#!│ RIDeletes │Version: 3007.103│
#!├──────────────────────────────┤Description├─────────────┴─────────────────┤
#!│Purpose: Constructs RI Delete code │
#!│Called From: FORM.TPX and MULTIPG.TPX (Near the end) │
#!│Assumptions: None │
#!│Inserts: WriteDeletes (perform RI deletes) │
#!│ InitLogout (performs transaction logging) │
#!│ RIRestrictMsg (warns user if constrained as restricted) │
#!│ AbortTransactionMsg (warns user if transaction aborted) │
#!│ RIDeleteError (warns user on RI delete error) │
#!│Symbols Set: None │
#!│Notes: None │
#!├───────────────────────────────┤Comments├─────────────────────────────────┤
#!│Version Comments │
#!│──────── ────────────────────────────────────────────────────────────────│
#!│3007.000 Release of CDD3 version 3007 templates │
#!│3007.101 Repaired code generating the %LogoutList symbol. Primary needed│
#!│ to be added to the list. │
#!│3007.103 Moved AbortTransactionMsg #INSERT to build and display the │
#!│ message before the ROLLBACK occurs. This was done because │
#!│ the error is reset after ROLLBACK. In addition, the ShowWarning│
#!│ was removed from the AbortTransactionMsg #GROUP and placed after│
#!│ the ROLLBACK. │
#!└──────────────────────────────────────────────────────────────────────────┘
#!
#GROUP(%RIDeletes) #!Perform Referential Deletes
#FOR(%File) #!Cycle through each file
#SET(%FileIsParent,%Null) #!Is the file a parent?
#SET(%FileIsChild,%Null) #!Is the file a child?
#SET(%RIDeleteNeeded,%Null) #!Is an RI Delete necessary?
#SET(%CheckPre,('['&%FilePre&']')) #!Setup to find %File Prefix
#IF((INSTRING(%CheckPre,%DeleteParentList,1,1))) #!Search for file as parent
#SET(%FileIsParent,'TRUE') #!If it is, set that flag
#SET(%RIDeleteNeeded,'TRUE') #!And RI Routine is needed
#ENDIF #!END (IF a Parent)
#IF((INSTRING(%CheckPre,%DeleteChildList,1,1))) #!Search for file as child
#SET(%FileIsChild,'TRUE') #!If it is, set that flag
#SET(%RIDeleteNeeded,'TRUE') #!And RI Routine is needed
#ENDIF #!END (IF a Child)
#IF(%RIDeleteNeeded) #!If we need to delete children
#IF(%FIleIsChild) #!If the file is a child
#FOR(%Relation) #!For Every Relation
#SET(%RelationString,('['&%RelationPre&'∙'&%FilePre&']'))
#!Setup to find child relation
#IF((INSTRING(%RelationString,%DeleteRelations,1,1)))
#!If the file is child
#INSERT(%WriteDeletes) #!Write the delete code
#ENDIF #!END (If file is child)
#ENDFOR #!END (For Relation)
#ELSE #!ELSE (File is parent only)
#INSERT(%WriteDeletes) #!Write the Delete Code
#ENDIF #!END (If File is Child)
#ENDIF #!END (IF Delete Needed)
#ENDFOR #!END (For File)
#IF(%DeleteChildList) #!IF RI Delete Children
!─────────────────────────────────────────────────────────────────────────────
ConstrainedDelete ROUTINE !Perform RI Deletes
CLEAR(RI:RestrictDelete,0) ! Clear Restrict Flag
CLEAR(AbortTransaction,0) ! Clear ABORT flag
DO OpenRIDeleteFiles
#SET(%LogoutFrom,'Delete')
#INSERT(%InitLogout) #!Insert Logout Code
DO Delete:%Primary #<! Perform the Deletes
IF RI:RestrictDelete #<! If delete was restricted
#INSERT(%RIRestrictMsg) #!Alert the user
#IF(%NoLogoutSupport=%Null) #!If supporting logout
ROLLBACK #<! Rollback transaction
#ENDIF #!END (If supporting logout)
AbortTransaction = True #<! Set the ABORT flag
#IF(%CloseFiles)
DO CloseRIDeleteFiles
#ENDIF
EXIT #<! and exit the routine
END #<! END (If restricted delete)
DELETE(%Primary) #<! Put %Primary
#IF(%NoLogoutSupport=%Null) #!If supporting logout
IF ~ERRORCODE() #<! If the Parent delete Ok
COMMIT ! Commit the transaction
ELSE ! else on any error
AbortTransaction = True ! Set the ABORT flag
#INSERT(%AbortTransactionMsg) #! Write Messages
ROLLBACK ! Rollback the transaction
ShowWarning ! Show warning
END ! End If ErrorCode()
#ELSE #!NoLogoutSupport
IF ERRORCODE() #<! Was the delete ok?
AbortTransaction = True ! Set the ABORT flag
#INSERT(%RIDeleteError) #! Alert the user
END ! END (If ErrorCode)
#ENDIF #!END (If supporting logout)
#IF(%CloseFiles)
DO CloseRIDeleteFiles
#ENDIF
EXIT #<! EXIT ConstrainedDelete
!─────────────────────────────────────────────────────────────────────────────
OpenRIDeleteFiles ROUTINE #<!Open files used in update
#FOR(%File) #!For Each File
#SET(%ChildString,('['&%FilePre&']')) #!Setup to find as child
#IF((INSTRING(%ChildString,%DeleteChildList,1,1)))#!If %File is Child
#IF(%CloseFiles) #!If Closing opened files
%FilePre::Opened = CheckOpen(%File) #<! Open %FIle (If Necessary)
#ELSE #!ELSE (If not closing files)
CheckOpen(%File) #<! Open %FIle (If Necessary)
#ENDIF #!END (If Closing open files)
#ENDIF #!END (If file is child)
#ENDFOR #!END (For Each File)
#IF(%CloseFiles)
!─────────────────────────────────────────────────────────────────────────────
CloseRIDeleteFiles ROUTINE
#FOR(%File) #!For Each File
#SET(%ChildString,('['&%FilePre&']')) #!Setup to find as child
#IF((INSTRING(%ChildString,%DeleteChildList,1,1)))#!If %File is Child
IF %FilePre::Opened THEN CLOSE(%File). #<! IF Opened here, close here
#ENDIF #!END (If file is child)
#ENDFOR #!END (For Each File)
#ENDIF
#ENDIF #!END (If delete Child)
#!***************************************************************************
#GROUP(%WriteDeletes) #! Write Delete Routines
#IF(%FileIsChild) #!If the File is Child
!─────────────────────────────────────────────────────────────────────────────
Delete:%RelationPre::%FilePre ROUTINE #<!%Relation - %File
!Constraint: %RelationConstraintDelete
#ELSE #!Otherwise (Parent Only)
!─────────────────────────────────────────────────────────────────────────────
Delete:%File ROUTINE #<!Delete Parent Record
#ENDIF #!END (If Child)
#SET(%SaveFile,%File) #!Save File for later use
#SET(%SaveRelation,%Relation) #!Save Relation for later use
#IF(%FileIsChild) #!Is the file a child
#FIX(%File,%SaveRelation) #!And swap the relationship
#FIX(%Relation,%SaveFile) #!for correct symbol access
GET(%Relation,0) #<! Disconnect record buffer
CLEAR(%RelationPre:Record,-1) #<! Clear %Relation record
#SET(%KeyFieldCounter,'0') #!Clear Field Counter
#!Field Counter is used to
#!construct a readable IF
#!structure inside loop.
#!Inside the loop, we search
#!each field of key, but use
#!Field Counter instead of
#!%RelationalKeyFieldLink
#FOR(%RelationKeyField) #!For each field in key
#IF(%RelationKeyFieldLink) #!If the field is linked
#SET(%KeyFieldCounter,(%KeyFieldCounter+1)) #!Increment Field Counter
%RelationKeyField = %RelationPre::%RelationKeyFieldLink #<! Set to original value
#ENDIF #!END (If field is linked)
#ENDFOR #!END (For relation field)
SET(%RelationKey,%RelationKey) #<! Set for sequential access
LOOP ! Search through records
NEXT(%Relation) #<! Get the next record
IF ERRORCODE() THEN BREAK. ! If out of records, break.
#SET(%IfWritten,%Null) #!Prepare For If Structure
#FOR(%RelationKeyField) #!For each field in key
#IF(%KeyFieldCounter='1') #!If this is last link field
#IF(%IfWritten) #!If the IF statement written
OR %RelationKeyField <> %RelationPre::%RelationKeyFieldLink #<! Check against save value
#ELSE #!If IF not written yet
IF %RelationKeyField <> %RelationPre::%RelationKeyFieldLink #<! Check against save value
#ENDIF #!END (If IF Written)
#BREAK #!Break out of loop
#ELSE #!otherwise (Counter > 1)
#IF(%IfWritten) #!If the IF statement written
OR %RelationKeyField <> %RelationPre::%RelationKeyFieldLink|#<! Check against save value
#ELSE #!If IF not written yet
IF %RelationKeyField <> %RelationPre::%RelationKeyFieldLink|#<! Check against save value
#ENDIF #!END If IF statement written
#ENDIF #!END (If Field Counter = 1)
#SET(%KeyFieldCounter,(%KeyFieldCounter-1)) #!Decrement Counter
#SET(%IfWritten,'TRUE') #!SET IF Statement written flag
#ENDFOR #!END (For Relation Field)
BREAK ! Break out of delete loop
END ! END (If out of range)
#IF(%RelationConstraintDelete = 'RESTRICT')#!If RESTRICTed delete
ri:RestrictDelete = True #<! Set Restricted Delete flag
BREAK ! BREAK from processing loop
#ELSE #!ELSE (If not RESTRICT)
#FIX(%File,%SaveFile) #!Reset the file to original
#IF(%FileIsParent) #!File is both Parent and Child
#FOR(%Relation) #!Get Each Relation
#SET(%RelationString,('['&%FilePre&'∙'&%RelationPre&']'))
#!Setup to find relationship
#IF((INSTRING(%RelationString,%DeleteRelations,1,1)))
#!Search for Relationship
#!In Delete Relation List
#FOR(%RelationKeyField) #!For Each Field of Key
#IF(%RelationKeyFieldLink) #!If the field is linked
%RelationPre::%RelationKeyFieldLink = %RelationKeyFieldLink #<! Save Link Field Value
#ENDIF #!END (IF Field is linked)
#ENDFOR #!END (FOR Each Key Field)
DO Delete:%FilePre::%RelationPre #<! Call Delete Routine
IF ri:RestrictDelete THEN EXIT. ! If Restrict then exit
#ENDIF #!END (IF valid relationship)
#ENDFOR #!END (FOR Relation)
#ENDIF #!END (File is Parent)
#IF(%RelationConstraintDelete = 'CASCADE')#!IF CASCADE constraint
DELETE(%File) #<! DELETE record
#ELSIF(%RelationConstraintDelete = 'CLEAR') #! If we clear link fields
#FOR(%RelationKeyField) #!For each field in key
#IF(%RelationKeyFieldLink) #!If the field is linked
CLEAR(%RelationKeyField,0) #<! Clear link field value
#ENDIF #!END (If field is linked)
#ENDFOR #!END (For relation field)
PUT(%File) #<! And put cleared record
#ENDIF #!END (If file is parent)
#ENDIF #!END (If RESTRICT Constraint)
END ! END loop
EXIT ! Exit to calling routine
#ELSE #!ELSE (If NOT a child)
#!This applies only to
#!%Primary
#FOR(%Relation) #!For each Relation
#SET(%RelationString,('['&%FilePre&'∙'&%RelationPre&']'))
#!Setup to find relationship
#IF((INSTRING(%RelationString,%DeleteRelations,1,1)))
#!Search for Relationship
#!In Delete Relation List
DO Delete:%FilePre::%RelationPre #<! Call Delete Routine
IF ri:RestrictDelete THEN EXIT. ! If Restrict then exit
#ENDIF #!END (IF valid relation)
#ENDFOR #!END (FOR each relation)
EXIT #<! Exit to calling routine
#ENDIF #!ELSE (File is child)
#!****************************************************************************
#GROUP(%InitLogout) #!Initialize and check logout
#!
#!┌────────────────────────────┤Template Group├────────────┬─────────────────┐
#!│ InitLogout │Version: 3007.105│
#!├──────────────────────────────┤Description├─────────────┴─────────────────┤
#!│Purpose: Generate the code necessary for Transaction Framing │
#!│Called From: RIUpdates and RIDeletes GROUPs │
#!│Assumptions: None │
#!│Inserts: DriverCheck GROUP │
#!│ TransactionLockMsg │
#!│ TransactionErrorMsg │
#!│ BtrieveTrxFraming │
#!│Symbols Set: None │
#!│Notes: None │
#!├───────────────────────────────┤Comments├─────────────────────────────────┤
#!│Version Comments │
#!│──────── ────────────────────────────────────────────────────────────────│
#!│3007.000 Release of CDD3 version 3007 templates │
#!│3007.105 Restructured the INSERTS of TransactionLockMsg and │
#!│ TransactionErrorMsg to set GLO:Messagex variables before the │
#!│ ROLLBACK. │
#!└──────────────────────────────────────────────────────────────────────────┘
#!
#IF(%NoLogoutSupport=%Null) #! If logout supported
#SET(%LogoutList,(','&%Primary)) #! Initialize Logout List
#FOR(%File) #! For Each File
#SET(%ChildString,('['&%FilePre&']')) #! Setup to find as child
#IF(%LogoutFrom='Update') #! IF called from RIUpdates
#IF((INSTRING(%ChildString,%UpdateChildList,1,1)))#! If %File is Child
#INSERT(%DriverCheck) #! Check for Driver Type
#SET(%LogoutList,(%LogoutList&','&%File))#! Append %File to Logout List
#ENDIF #! END (IF %File is Child)
#ELSE #! ELSE (NOT called from RIUpdates)
#IF((INSTRING(%ChildString,%DeleteChildList,1,1)))#!If %File is Child
#INSERT(%DriverCheck) #! Check for Driver Type
#SET(%LogoutList,(%LogoutList&','&%File))#! Append %File to Logout List
#ENDIF #! END (IF %File is Child)
#ENDIF #! END (If file is child)
#ENDFOR #! END (For Each File)
#SET(%LogoutList,('logout(2'&%LogoutList&')')) #! Prepare the logout code line
%LogoutList #<! Begin the transaction
IF ERRORCODE() #<! If logout unsuccessful
AbortTransaction = True #<! Set the Abort Flag
CASE ERRORCODE() #<! Check the errorcode
OF IsLockedErr #<! IF File Locked
#INSERT(%TransactionLockMsg) #! Alert the user
ELSE #<! Other Error
#INSERT(%TransactionErrorMsg) #! Alert the user
END #<! END (If File Locked)
ROLLBACK #<! Rollback the transaction
ShowWarning #<! Display the error
DISABLE(1,FIELDS()) #<! Disable the screen fields
#IF(%FirstField) #! If First Field Designated
ENABLE(%FirstField) #<! Enable First Field
SELECT(%FirstField) #<! Select First Entry Field
#ELSE #! Otherwise (~%FirstField)
#FIX(%ScreenField,'?Cancel') #! Try to get the Cancel button
#IF(%ScreenField) #! If we have a ?Cancel button
ENABLE(?Cancel) #<! Enable the ?Cancel Button
SELECT(?Cancel) #<! Select the ?Cancel Button
#ELSE #! If no ?Cancel Button
#FIX(%ScreenField,'?OK') #! Try to get the Cancel button
#IF(%ScreenField) #! If we have a ?Cancel button
ENABLE(?OK) #<! Enable the ?OK Button
SELECT(?OK) #<! Select the ?OK Button
#ENDIF #! END (If ?OK Button)
#ENDIF #! END (If ?Cancel Button)
#ENDIF #! END (If %FirstField)
#IF(%CloseFiles) #! IF Closing Unused Files
#IF(%LogoutFrom='Update') #! IF Called from Update
DO CloseRIUpdateFiles #<! Close files used
#ELSE #! ELSE (IF Called from Delete)
DO CloseRIDeleteFiles #<! Close files used
#ENDIF #! END (IF Called...)
#ENDIF #! END (IF Closing Unused...)
EXIT #<! Exit the Routine
END #<! No errors, start transaction
#INSERT(%BtrieveTrxFraming) #! Btrieve transaction system
#! requires that the acquisition
#! of the record affected by the
#! put take place between the
#! logout and commit
#ENDIF #! END (If logout supported)
#!***************************************************************************
#GROUP(%BtrieveTrxFraming) #!Initialize Btrieve Transaction
#!
#!┌────────────────────────────┤Template Group├────────────┬─────────────────┐
#!│ BtrieveTrxFraming │Version: 3007.105│
#!├──────────────────────────────┤Description├─────────────┴─────────────────┤
#!│Purpose: Generate code to construct proper Btrieve transaction │
#!│Called From: InitLogout GROUP │
#!│Assumptions: None │
#!│Inserts: RIRecNotAvailMsg GROUP │
#!│Symbols Set: None │
#!│Notes: None │
#!├───────────────────────────────┤Comments├─────────────────────────────────┤
#!│Version Comments │
#!│──────── ────────────────────────────────────────────────────────────────│
#!│3007.000 Release of CDD3 version 3007 templates │
#!│3007.105 Restructured the INSERT of RIRecNotAvailMsg to set │
#!│ GLO:Messagex variables before the ROLLBACK. │
#!└──────────────────────────────────────────────────────────────────────────┘
#!
#IF(%PrimaryDriver='Btrieve') #!If %Primary uses Btrieve
SAV:SaveRecord = %FilePre:Record #<! Save the record image
#FOR(%FileMemo) #!For each memo
#FIX(%Field,%FileMemo) #!Get the Field ID
SAV:%FieldID = %FileMemo #<! Save the memo image
#ENDFOR #!END (For each memo)
SAV:Position = POSITION(%Primary) #<! Save the record position
RESET(%Primary,SAV:Position) #<! and reset to position
NEXT(%Primary) #<! and reread the record
IF SAV:Position <> POSITION(%Primary) #<! If on a different record
AbortTransaction = True #<! ABORT the Update
#INSERT(%RIRecNotAvailMsg) #! Alert the user
ROLLBACK #<! Roll back changes
ShowWarning #<! Alert the User
EXIT #<! And leave the routine
END #<! END (If not good record)
%FilePre:Record = SAV:SaveRecord #<! Reset Record Value
#FOR(%FileMemo) #!For each memo
#FIX(%Field,%FileMemo) #!Fix the memo field
%FileMemo = SAV:%FieldID #<! Reset the memo value
#ENDFOR #!END (For each memo)
#ENDIF #!END (If using Btrieve)
#!***************************************************************************
#GROUP(%SavePrimaryLinks) #!Save Links to Primary
#FIX(%File,%Primary) #!Setup to read primary
#FOR(%Relation) #!Get Each Relation
#SET(%RelationString,('['&%FilePre&'∙'&%RelationPre&']'))
#!Setup to find relationship
#IF((INSTRING(%RelationString,%AllRelations,1,1)))
#!Search for Relationship
#!In Update Relation List
#FOR(%RelationKeyField) #!For Each Field of Key
#IF(%RelationKeyFieldLink) #!If the field is linked
%RelationPre::%RelationKeyFieldLink = %RelationKeyFieldLink #<! Save Link Field Value
#ENDIF #!END (IF Field is linked)
#ENDFOR #!END (FOR Each Key Field)
#ENDIF #!END (IF valid relationship)
#ENDFOR #!END (FOR Relation)
#!***************************************************************************
#GROUP(%ConcurrentWrite)
#IF(%SharedFiles)
!─────────────────────────────────────────────────────────────────────────────
ConcurrentWrite ROUTINE
CLEAR(AbortTransaction,0) #<!Initialize AbortWrite#
#IF(%AutoInc)
IF AutoIncAdd THEN EXIT. #<!Not an Autoincrement ADD
#ENDIF
GET(RecordQueue,2) #<!Add the changed record
Sav:SaveRecord = %FilePre:Record #<!Save Record to the Queue
#IF(%MemoChk)
#FOR(%FileMemo)
#FIX(%Field,%FileMemo)
SAV:%FieldID = %FileMemo #<!Save Memo to the Queue
#ENDFOR
#ENDIF
PUT(RecordQueue)
GET(RecordQueue,1) #<!Get the original record
RESET(%Primary,SavePointer) #<!Position to record on disk
HOLD(%Primary,2) #<!Set HOLD retry for 2 seconds
NEXT(%Primary) #<!Read the record into buffer
IF ERRORCODE() #<!Was there an error?
CASE ERRORCODE() #<!Process recoverable errors
OF IsHeldErr #<!Record is already held
#INSERT(%TransactionHeldMsg)
SELECT(1) #<!Place cursor on 1st field
RELEASE(%Primary) #<!Release the HOLD
AbortTransaction = True #<!Turn on AbortWrite#
EXIT #<!Back to main Loop
ELSE #<!On any other error
IF DiskError('File Access Error') #<!Call the Diskerror function
RELEASE(%Primary) #<!Release the hold
FREE(RecordQueue) #<!Free the memory Queue
DISABLE(1,FIELDS()) #<!Disable all screen fields
#IF(%FirstField) #!If First Field Designated
ENABLE(%FirstField) #<! Enable First Field
SELECT(%FirstField) #<! Select First Entry Field
#ELSE #!Otherwise (~%FirstField)
#FIX(%ScreenField,'?Cancel') #!Try to get the Cancel button
#IF(%ScreenField) #!If we have a ?Cancel button
ENABLE(?Cancel) #<! Enable the ?Cancel Button
SELECT(?Cancel) #<! Select the ?Cancel Button
#ELSE #!If no ?Cancel Button
#FIX(%ScreenField,'?OK') #!Try to get the Cancel button
#IF(%ScreenField) #!If we have a ?Cancel button
ENABLE(?OK) #<! Enable the ?OK Button
SELECT(?OK) #<! Select the ?OK Button
#ENDIF #!END (If ?OK Button)
#ENDIF #!END (If ?Cancel Button)
#ENDIF #!END (If %FirstField)
AbortTransaction = True #<!Turn on AbortWrite#
EXIT #<!and exit the routine
END #<!End IF Diskerror
END #<!End CASE Errorcode()
ELSIF Sav:SaveRecord <> %FilePre:Record #<!Has the record been changed
Sav:SaveRecord = %FilePre:Record #<!Then update the Queue record
#IF(%MemoChk = 'Y')
#FOR(%FileMemo)
#FIX(%Field,%FileMemo)
SAV:%FieldID = %Field #<!Then update the Queue memo
#ENDFOR
#ENDIF
#INSERT(%ConflictUpdate)
#IF(%MemoChk = 'Y')
#FOR(%FileMemo)
#FIX(%Field,%FileMemo)
ELSIF SAV:%FieldID <> %Field #<!Has the Memo been changed?
SAV:%FieldID = %Field #<!Then update the Queue memo
#INSERT(%ConflictUpdate)
#ENDFOR
#ENDIF
ELSE #<!Its ok to update the file
GET(RecordQueue,2) #<!Retrieve the users changes
%FilePre:Record = Sav:SaveRecord #<!Move changes to record buffer
#IF(%MemoChk)
#FOR(%FileMemo)
#FIX(%Field,%FileMemo)
%Field = SAV:%FieldID #<!Move Memo to buffer
#ENDFOR
#ENDIF
END #<!End IF Errorcode()
EXIT
#ENDIF
#!***************************************************************************
#GROUP(%ConcurrentDelete)
#IF(%SharedFiles)
!─────────────────────────────────────────────────────────────────────────────
ConcurrentDelete ROUTINE
AbortTransaction = False
RESET(%Primary,SavePointer) #<!Set position in Primary file
HOLD(%Primary,2) #<!Hold the record
NEXT(%Primary) #<!Read the record into buffer
IF ERRORCODE() #<!Check for file access error
CASE ERRORCODE() #<!Case for recoverable errors
OF IsHeldErr #<!Record is already held
#INSERT(%TransactionHeldMsg)
SELECT(1) #<!Place cursor on 1st field
RELEASE(%Primary) #<!Release HOLD request
AbortTransaction = True #<!Set AbortDelete# ON
EXIT #<!Re-start main LOOP
ELSE #<!for any other error
IF DiskError('Unable to process current Record') #<!Call error function
#INSERT(%UnableToContinueMsg)
DO ProcedureReturn
END #<!End IF Diskerror
END #<!End CASE errorcode
ELSIF POSITION(%Primary) <> SavePointer #<!Is the record already deleted?
RELEASE(%Primary) #<!Relase record Hold
DO ProcedureReturn #<!Return to the calling procedure
END #<!End IF errorcode()
EXIT
#ENDIF
#!***************************************************************************
#GROUP(%DriverCheck)
#!
#!┌────────────────────────────┤Template Group├────────────┬─────────────────┐
#!│ DriverCheck │Version: 3007.101│
#!├──────────────────────────────┤Description├─────────────┴─────────────────┤
#!│Purpose: Checks that all files use the same driver │
#!│Called From: FORM and MULTIPG │
#!│Assumptions: None │
#!│Inserts: None │
#!│Symbols Set: None │
#!│Notes: None │
#!├───────────────────────────────┤Comments├─────────────────────────────────┤
#!│Version Comments │
#!│──────── ────────────────────────────────────────────────────────────────│
#!│3007.000 Release of CDD3 version 3007 templates │
#!│3007.101 Changed comparison of %NoLogoutSupport to any non-null value. │
#!└──────────────────────────────────────────────────────────────────────────┘
#!
#IF(NOT %NoLogoutSupport)
#IF(%FileType <> %PrimaryDriver)
#SET(%ErrorMessage,%NULL)
#ERROR(%ErrorMessage)
#SET(%ErrorMessage,(' WARNING during Source Code Generation in Procedure: '& %Procedure ))
#ERROR(%ErrorMessage)
#SET(%ErrorMessage, ' the FILE Relationship uses multiple file drivers')
#ERROR(%ErrorMessage)
#SET(%ErrorMessage,(' see FORM Template Help, TOPIC: No Transaction Framing'))
#ERROR(%ErrorMessage)
#SET(%ErrorMessage,(' Set "Disable RI Logout" in Procedure Properties'))
#ERROR(%ErrorMessage)
#SET(%ErrorMessage,(' to prevent this message from appearing.'))
#ERROR(%ErrorMessage)
#SET(%ErrorMessage, %NULL)
#ERROR(%ErrorMessage)
#SET(%NoLogoutSupport,'Y')
#ENDIF
#ENDIF
#!***************************************************************************
#GROUP(%PrimaryDriverCheck)
#!
#!┌────────────────────────────┤Template Group├────────────┬─────────────────┐
#!│ PrimaryDriverCheck │Version: 3007.101│
#!├──────────────────────────────┤Description├─────────────┴─────────────────┤
#!│Purpose: Checks if the Driver for %Primary supports LOGOUT │
#!│Called From: FORM and MULTIPG │
#!│Assumptions: None │
#!│Inserts: None │
#!│Symbols Set: None │
#!│Notes: None │
#!├───────────────────────────────┤Comments├─────────────────────────────────┤
#!│Version Comments │
#!│──────── ────────────────────────────────────────────────────────────────│
#!│3007.000 Release of CDD3 version 3007 templates │
#!│3007.101 Added check of %NoLogoutSupport coming in to group │
#!└──────────────────────────────────────────────────────────────────────────┘
#!
#IF(NOT %NoLogoutSupport)
#IF((UPPER(%PrimaryDriver) <> 'BTRIEVE') AND (UPPER(%PrimaryDriver) <> 'CLARION'))
#SET(%ErrorMessage,%NULL)
#ERROR(%ErrorMessage)
#SET(%ErrorMessage,(' WARNING during Code Generation in Procedure: '& %Procedure ))
#ERROR(%ErrorMessage)
#SET(%ErrorMessage,( ' PRIMARY file driver (' & %PrimaryDriver & ') does not support LOGOUT() '))
#ERROR(%ErrorMessage)
#SET(%ErrorMessage,(' see FORM Template Help, Topic: No Transaction Framing'))
#ERROR(%ErrorMessage)
#SET(%ErrorMessage,(' Set "Disable RI Logout" in Procedure Properties'))
#ERROR(%ErrorMessage)
#SET(%ErrorMessage,(' to prevent this message from appearing.'))
#ERROR(%ErrorMessage)
#SET(%NoLogoutSupport,'Y')
#ENDIF
#ENDIF
#CHAIN('ScrnFlds.TPX')